using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Framework.Interop
{
    [ComVisible(false)]
    internal sealed class Win32Window : IWin32Window
    {
        internal static IWin32Window Create(IntPtr hwnd)
        {
            return hwnd == IntPtr.Zero ? null : new Win32Window(hwnd);
        }

        private readonly IntPtr _hwnd;

        private Win32Window(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero)
            {
                throw new ArgumentNullException("hwnd");
            }

            this._hwnd = hwnd;
        }

        IntPtr IWin32Window.Handle
        {
            get { return this._hwnd; }
        }
    } ;

    [ComVisible(false)]
    internal sealed class Win32WindowMarshaler : ICustomMarshaler
    {
        private static ICustomMarshaler _instance;

        public static ICustomMarshaler GetInstance(string cookie)
        {
            return _instance ?? (_instance = new Win32WindowMarshaler());
        }

        private Win32WindowMarshaler()
        {
        }

        void ICustomMarshaler.CleanUpManagedData(object managedObj)
        {
        }

        void ICustomMarshaler.CleanUpNativeData(IntPtr pNativeData)
        {
        }

        int ICustomMarshaler.GetNativeDataSize()
        {
            return IntPtr.Size;
        }

        IntPtr ICustomMarshaler.MarshalManagedToNative(object managedObj)
        {
            if (!(managedObj is IWin32Window))
            {
                throw new ArgumentOutOfRangeException("managedObj", managedObj, "expected an IWin32Window");
            }

            return (managedObj as IWin32Window).Handle;
        }

        object ICustomMarshaler.MarshalNativeToManaged(IntPtr pNativeData)
        {
            return Win32Window.Create(pNativeData);
        }
    } ;
}
